/**
 *  Serponix is an arcade game in focus to multiplayer based on the classic game Snake.
 *  Copyright (C) 2010 - 2011  Daniel Vala
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License,
 *  or  any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.

 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 *  If you have any question do not hesitate to contact author
 *  on e-mail address: danielvala42@gmail.com
 */
package com.serponix.game;

import com.serponix.game.food.Cake;
import com.serponix.game.food.Cherry;
import com.serponix.game.score.Score;
import com.serponix.gui.WindowInterface;
import com.serponix.net.Informace;
import java.awt.Graphics;
import java.awt.Toolkit;
import java.util.Collections;
import javax.swing.JLabel;

/**
 * Dědí z Modelu, reprezentuje mód classic.
 *
 * @author Daniel Vala
 */
public class ModelClassic extends GameModel {

	private int vyskytBonusu = 3;
	private final int pocetBoduKJedneVyhre = 500;

	@SuppressWarnings("LeakingThisInConstructor")
	public ModelClassic(WindowInterface okno, GameParameters parametryHry, GamingArea herniPanel, JLabel[] skoreStitky, MessagePanel panelZprav) {
		super(okno, parametryHry, herniPanel, skoreStitky, panelZprav, parametryHry.getSizeOfGamingArea());
		parametryHry.getServer().setModel(this);
		net = parametryHry.getServer();
		hadi = new Snake[getPocetHadu()];
		vytvorListPocatecnichPozic(10);
		Collections.shuffle(listPocatecnichPozic);
		for (int i = 0; i < hadi.length; i++) {
			hadi[i] = new Snake(this, getHrac(i), listPocatecnichPozic.get(i), -1, Direction.DOWN, 3, getVelikostPolicka(), 10, 0, barvy[i], null, false, false);
			getHrac(i).init(this, hadi[i]);
		}
		jidlo = new Cake(this);

		startHry();
	}

	@Override
	public void jidloSezrano(Snake had) {
		had.prodluzHada();
		addScore(had.score, 50);
		jidlo.generateFood();
		int stesti = 1 + generatorNahody.nextInt(vyskytBonusu);
		if (stesti == 1 && bonus == null) {
			bonus = new Cherry(this);
		}
	}

	@Override
	public void bonusSezran(Snake had) {
		had.prodluzHada(6);
		addScore(had.score, 100);
		Toolkit.getDefaultToolkit().beep();
		bonus = null;
	}

	@Override
	public void resetHada(Snake had) {
		addScore(had.score, -10);
		Collections.shuffle(listPocatecnichPozic);
		had.setHad(listPocatecnichPozic.get(0), -1, Direction.DOWN);
	}

	@Override
	public void newRound() {
		Collections.shuffle(listPocatecnichPozic);
		Snake[] listHadu = getHadi();
		for (int i = 0; i < getPocetHadu(); i++) {
			listHadu[i].setHad(listPocatecnichPozic.get(i), -1, Direction.DOWN);
		}
		pockej(1000);
		jidlo.generateFood();
		bonus = null;
		ozivVsechnyHady();
	}

	@Override
	public void addScore(Score skore, int body) {
		skore.addSkore(body, pocetBoduKJedneVyhre);
	}

	// metoda krok kontroluje jestli had nenarazil do steny, jestli had neji a jestli had nenarazil do druheho hada
	@Override
	public void krok() {
		for (int i = 0; i < getPocetHadu(); i++) {
			getHrac(i).posunSe();
			setSkoreText(i, "Hrac " + getHrac(i).getJmeno() + ":   Skore: " + hadi[i].score.getSkore() + "   Vyhry: " + hadi[i].score.getPocetVyher() + "  |");
		}

		posliPole();
		posliStavStitku();
		posliInfo();
		posliKrok();

		setChanged();
		notifyObservers();
	}

	public void posliPole() {
		String zpravaKOdeslani = Informace.POLICKO + Informace.ODDELOVAC1;
		// přidání všech políček do zprávy
		if (jidlo != null) {
			zpravaKOdeslani += jidlo.getInstrukceProKresleni();
		}
		if (bonus != null) {
			zpravaKOdeslani += bonus.getInstrukceProKresleni();
		}
		for (int j = 0; j < getPocetHadu(); j++) {
			zpravaKOdeslani += hadi[j].getInstrukceProKresleni(false);
		}

		net.poslatData(zpravaKOdeslani);
	}

	public void posliKrok() {
		String zpravaKOdeslani = Informace.KROK + Informace.ODDELOVAC1;
		net.poslatData(zpravaKOdeslani);
	}

	public void posliStavStitku() {
		String zpravaKOdeslani = Informace.SKORE + Informace.ODDELOVAC1;

		// přidání textů všech štítků do zprávy
		for (int i = 0; i < getPocetHadu(); i++) {
			zpravaKOdeslani += getSkoreText(i) + Informace.ODDELOVAC3;
		}
		net.poslatData(zpravaKOdeslani);
	}

	public void posliInfo() {
		String zpravaKOdeslani = getPanelZprav().getMessageToSend();
		if (zpravaKOdeslani != null) {
			net.poslatData(zpravaKOdeslani);
		}
	}

	@Override
	public void paint(Graphics g) {
		if (!zobrazVeciNaPlose) {

			for (Snake had : hadi) {
				had.draw(g);
			}
			jidlo.draw(g);
			if (bonus != null) {
				bonus.draw(g);
			}
		} else {
			zobrazVeciNaPlose(g);
		}
	}

	@Override
	public void paintZdi(Graphics g) {
		getMapa().kresliMapu(g);
	}
}
